package com.fuyao.cloud.common.core.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * * 编码码生成器，生成编码，
 * * @生成规则 2位单号类型+17位时间戳+8位(用户id加密&随机数)
 *   @生成规则 2位单号类型+8位时间戳+8位(用户id加密&随机数)
 */
public class ServerNumberUtils {



	/**
	 * 随即编码
	 */

	private static final int[] r = new int[]{7, 9, 6, 2, 8, 1, 3, 0, 5, 4};
	/**
	 * 根据id进行加密+加随机数组成固定长度编码
	 * @param userId  用户ID
	 * @param maxLength  编码随机数长度
	 */
	private static String toCode(Integer userId,int maxLength) {
		String idStr = userId.toString();
		StringBuilder idsbs = new StringBuilder();
		for (int i = idStr.length() - 1; i >= 0; i--) {
			idsbs.append(r[idStr.charAt(i) - '0']);
		}
		return idsbs.append(getRandom(maxLength - idStr.length())).toString();
	}

	/**
	 * 生成时间戳
	 */
	private static String getDateTime() {
		DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		return sdf.format(new Date());
	}
	/**
	 * 生成时间戳
	 */
	private static String getDate() {
		DateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return sdf.format(new Date());
	}

	/**
	 * 生成固定长度随机码
	 * @param n 长度
	 */

	private static long getRandom(long n) {
		long min = 1, max = 9;
		for (int i = 1; i < n; i++) {
			min *= 10;
			max *= 10;
		}
		long rangeLong = (((long) (new Random().nextDouble() * (max - min)))) + min;
		return rangeLong;
	}


	/**
	 * 生成不带类别标头的编码
	 * @param userId   用户ID
	 * @param maxLength  编码随机数长度
	 */
	private static synchronized String getCodebyDateTime(Integer userId,int maxLength) {
		userId = userId == null ? 10000 : userId;
		return getDateTime() + toCode(userId,maxLength);
	}
	/**
	 * 生成不带类别标头的编码
	 * @param userId   用户ID
	 * @param maxLength  编码随机数长度
	 */
	private static synchronized String getCodeByDate(Integer userId,int maxLength) {
		userId = userId == null ? 10000 : userId;
		return getDate() + toCode(userId,maxLength);
	}

	/**
	 * 生成编码(调用方法) 生成规则 类型编码+8位时间戳+8位(用户id加密&随机数)
	 * @param numberType  编号类型
	 * @param userId  网站中该用户唯一ID 防止重复
	 * @param maxLength  编码随机数长度
	 */
	public  String getCodebyDate(String numberType,Integer userId,int maxLength) {
		return numberType + getCodeByDate(userId,maxLength);
	}

	/**
	 * 生成编码(调用方法)生成规则 类型编码+17位时间戳+8位(用户id加密&随机数)
	 * @param numberType  编号类型
	 * @param userId  网站中该用户唯一ID 防止重复
	 * @param maxLength  编码随机数长度
	 */
	public  String getCodebyDateTime(String numberType,Integer userId,int maxLength) {
		return numberType + getCodebyDateTime(userId,maxLength);
	}


	/**
	 * 保存生成一个编号格式为：{numberType+xxxx+num}
	 * @param numberType 编号类型
	 * @param year 年
	 * @return 编号
	 */
	public Integer getNumberTypebyYear(final String numberType, final Integer year){
		String sql="select t.count from FY_SERVER_NUMBER t where t.numberType= :numberType and t.code= :year ";
		Map<String, Object> paramMap = new HashMap<String, Object>() {{
			put("numberType", numberType);
			put("year", year);
		}};
		List list = null;//elereportDao.findBySQL(null, sql, paramMap);
		if(list.size()!= 0){
			Integer count = Integer.parseInt(list.get(0).toString());
			count++;
			String upsql = "update FY_SERVER_NUMBER t set t.count='"+count+"' where t.numberType='"+numberType+"' and t.code= '"+year+"'";
			//elereportDao.executeSQL(upsql,null);
			return count;
		}else {
			String insertSql ="insert into FY_SERVER_NUMBER (ID, NUMBERTYPE, CODE, COUNT) values ('id', '"+numberType+"', '"+year+"', '1') ";
			//elereportDao.executeSQL(insertSql,null);
			return Integer.parseInt("1");
		}
	}

	/**
	 * 保存生成一个编号格式为：{numberType+parentCode+num}
	 * @param numberType 编号类型
	 * @param parentCode 父编码
	 * @return 编号
	 */
	public Integer getNumberTypebyParent(final String numberType, final String parentCode){
		String sql="select t.count from FY_SERVER_NUMBER t where t.numberType= :numberType and t.code= :parentCode ";
		Map<String, Object> paramMap = new HashMap<String, Object>() {{
			put("numberType", numberType);
			put("year", parentCode);
		}};
		List list = null;//elereportDao.findBySQL(null, sql, paramMap);
		if(list.size()!= 0){
			Integer count = Integer.parseInt(list.get(0).toString());
			count++;
			String upsql = "update FY_SERVER_NUMBER t set t.count='"+count+"' where t.numberType='"+numberType+"' and t.code= '"+parentCode+"'";
			//elereportDao.executeSQL(upsql,null);
			return count;
		}else {
			String insertSql ="insert into FY_SERVER_NUMBER (ID, NUMBERTYPE, CODE, COUNT) values ('id', '"+numberType+"', '"+parentCode+"', '1') ";
			//elereportDao.executeSQL(insertSql,null);
			return Integer.parseInt("1");
		}
	}
}
